package com.example.demo.service;

import com.example.demo.config.MailAccountConfig;
import com.example.demo.config.MailServerConfig;
import org.springframework.stereotype.Service;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Map;
import java.util.Properties;

/**
 * 使用原生javaMail方式发送邮件
 */
@Service
public class JavaMailService {

    public final MailAccountConfig defaultMailAccountConfig;

    public final MailAccountConfig specialMailAccountConfig;

    public final Map<String, MailServerConfig> mailServerConfigMap;

    public JavaMailService(MailAccountConfig defaultMailAccountConfig, MailAccountConfig specialMailAccountConfig, Map<String, MailServerConfig> map) {
        this.defaultMailAccountConfig = defaultMailAccountConfig;
        this.specialMailAccountConfig = specialMailAccountConfig;
        this.mailServerConfigMap = map;
    }

    /**
     * 更完整的代码示例参考 com\example\demo\other\FastJavaMailDemo.java
     * @param sendTo       收件人邮箱
     * @param subject      邮件标题
     * @param emailContent 邮件内容
     */
    public void sendMailByJavaMail(String sendTo, String subject, String emailContent) {
        final Properties props = getProperties(defaultMailAccountConfig);

        // 构建授权信息，用于进行SMTP进行身份验证
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // 用户名、密码
                String userName = props.getProperty("mail.user");
                String password = props.getProperty("mail.password");
                return new PasswordAuthentication(userName, password);
            }
        };
        // 使用环境属性和授权信息，创建邮件会话
        Session mailSession = Session.getInstance(props, authenticator);
        // 创建邮件消息
        MimeMessage message = new MimeMessage(mailSession);
        try {
            // 设置发件人邮件地址和名称。填写控制台配置的发信地址,比如xxx@xxx.com。和上面的mail.user保持一致。名称用户可以自定义填写。
            InternetAddress from = new InternetAddress(props.getProperty("mail.user"), "发件人名称");
            message.setFrom(from);
            //可选。设置回信地址
            Address[] a = new Address[1];
            a[0] = new InternetAddress(props.getProperty("mail.user"));
            message.setReplyTo(a);
            // 设置收件人邮件地址，比如yyy@yyy.com
            InternetAddress to = new InternetAddress(sendTo);
            message.setRecipient(MimeMessage.RecipientType.TO, to);
            // 设置邮件标题
            message.setSubject(subject);
            // 设置邮件的内容体
            message.setContent(emailContent, "text/plain;charset=UTF-8");

            Transport.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据项目配置（服务器配置和账号配置）生成一个javaMail使用的Properties
     *
     * @param mailAccountConfig 其中一个账号配置
     * @return
     */
    private Properties getProperties(MailAccountConfig mailAccountConfig) {

        // 根据账号获取服务器配置
        MailServerConfig mailServerConfig = mailServerConfigMap.get(mailAccountConfig.getType());

        // 发邮件使用smtp服务器
        MailServerConfig.Protocol protocol = mailServerConfig.getHost().get("smtp");

        // 配置发送邮件的环境属性
        final Properties props = new Properties();
        // 表示SMTP发送邮件，需要进行身份验证
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", protocol.getHost());
        props.put("mail.smtp.port", Integer.parseInt(protocol.getPort()));
        props.put("mail.user", mailAccountConfig.getUsername());
        // 访问SMTP服务时需要提供的密码(在控制台选择发信地址进行设置)
        props.put("mail.password", mailAccountConfig.getPassword());
        return props;
    }
}
